import 'package:flutter/material.dart';
import 'package:lib_uikit/lib_uikit.dart';

enum GTProgressV3Style {
  normal,
  error,
  black,
}

extension _StyleRenderInfo on GTProgressV3Style {
  Color get lineColor => {
        GTProgressV3Style.normal: GTColorsV3.uikitBrand3V3.color,
        GTProgressV3Style.error: GTColorsV3.uikitFunct3V3.color,
        GTProgressV3Style.black: GTColorsV3.icon2.color,
      }[this]!;

  Icon? get icon => {
        GTProgressV3Style.normal: null,
        GTProgressV3Style.error: Icon(GTIconFont.e7eb, color: lineColor, size: 12),
        GTProgressV3Style.black: null,
      }[this];
}

class GTProgressV3 extends StatelessWidget {
  /// 左边主标题
  final String? leftHead;

  /// 左边副标题
  final String? leftSubHead;

  /// 右边标题
  final String? rightHead;

  /// 是否显示进度tip
  final bool tooltipVisible;

  /// 进度条值[0.0-1.0]
  final double progress;

  ///自定义展示右侧progress文案
  final String? progressText;
  final bool? showProgressText;

  /// 带渐变进度条初始化
  const GTProgressV3.gradient({
    super.key,
    this.leftHead,
    this.leftSubHead,
    this.rightHead,
    this.tooltipVisible = false,
    required this.progress,
    this.progressText,
    this.showProgressText,
  })  : assert(progress <= 1.0 && progress >= 0.0, 'progress min 0.0, max 1.0'),
        assert((leftHead == null && leftSubHead == null && rightHead == null) || !tooltipVisible,
            'text or tooltip only choose one'),
        _style = GTProgressV3Style.normal,
        _gradientVisible = true;

  /// 纯色进度条初始化
  const GTProgressV3.line(
      {super.key,
      GTProgressV3Style style = GTProgressV3Style.normal,
      this.leftHead,
      this.leftSubHead,
      this.rightHead,
      this.tooltipVisible = false,
      required this.progress,
      this.progressText,
      this.showProgressText = true})
      : assert(progress <= 1.0 && progress >= 0.0, 'progress min 0.0, max 1.0'),
        assert((leftHead == null && leftSubHead == null && rightHead == null) || !tooltipVisible,
            'text or tooltip only choose one'),
        _style = style,
        _gradientVisible = false;

  /// 进度条样式
  final GTProgressV3Style _style;

  /// 是否显示渐变,如果为true，进度条[style]为[GTProgressV3Style.normal]
  final bool _gradientVisible;

  @override
  Widget build(BuildContext context) {
    final showIcon = _style.icon != null;
    final showHead = leftHead != null || leftSubHead != null || rightHead != null;
    final showTooltip = tooltipVisible;
    final _progressText = progressText ?? "";

    return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        if (showIcon) ...[_style.icon!, const SizedBox(width: 4)],
        Expanded(
          child: Column(
            children: [
              if (showHead) ...[_buildHead(), const SizedBox(height: 4)],
              if (showTooltip) ...[_buildTooltip(), const SizedBox(height: 4)],
              _buildLine(),
              if (showIcon) const SizedBox(height: 4),
            ],
          ),
        ),
        if (_style == GTProgressV3Style.black && (showProgressText ?? true)) ...[
          const SizedBox(width: 4),
          Transform.translate(
            offset: const Offset(0, 6),
            child: Text(
              _progressText.isEmpty ? "${(progress * 100).toStringAsFixed(0)}%" : _progressText,
              style: gtTextStyleW500(fontSize: 11, color: GTColorsV3.text3.color),
            ),
          ),
        ]
      ],
    );
  }

  Widget _buildHead() {
    return SizedBox(
      height: 17,
      child: Row(
        children: [
          if (leftHead != null)
            Text(leftHead!, style: gtTextStyleW400(fontSize: 14, color: GTColorsV3.uikitText1V3.color)),
          const SizedBox(width: 4),
          if (leftSubHead != null)
            Text('/$leftSubHead', style: gtTextStyleW400(fontSize: 14, color: GTColorsV3.uikitText3V3.color)),
          const Spacer(),
          if (rightHead != null)
            Text(rightHead!, style: gtTextStyleW400(fontSize: 14, color: GTColorsV3.uikitText5V3.color)),
        ],
      ),
    );
  }

  Widget _buildTooltip() {
    return SizedBox(
      height: 20,
      width: double.infinity,
      child: CustomPaint(
        painter: _TooltipPainter(style: _style, progress: progress),
      ),
    );
  }

  Widget _buildLine() {
    return SizedBox(
      height: 4,
      width: double.infinity,
      child: CustomPaint(
        painter: _ProgressPainter(style: _style, gradientVisible: _gradientVisible, progress: progress),
      ),
    );
  }
}

class _TooltipPainter extends CustomPainter {
  _TooltipPainter({required this.style, required this.progress});

  final GTProgressV3Style style;

  final double progress;

  final Paint _paint = Paint()..style = PaintingStyle.fill;

  @override
  void paint(Canvas canvas, Size size) {
    // 左右间距
    const int horizontalPadding = 4;

    // 计算宽度
    String tipString = '${(progress * 100).toStringAsFixed(0)}%';
    final textStyle = TextStyle(color: GTColorsV3.text6.dark, fontSize: 12);
    final textSpan = TextSpan(text: tipString, style: textStyle);
    final textPainter = TextPainter(text: textSpan, textDirection: TextDirection.ltr, textAlign: TextAlign.center);
    textPainter.layout(minWidth: 0, maxWidth: size.width);
    final textWidth = textPainter.width;
    final textHeight = textPainter.height;

    // 绘制背景
    double bgWidth = textWidth + horizontalPadding * 2;
    double bgLeft = (progress * size.width - textWidth / 2 - horizontalPadding).clamp(0, size.width - bgWidth);
    double bgRight = bgLeft + bgWidth;
    final bgRect = RRect.fromLTRBR(bgLeft, 0, bgRight, size.height, const Radius.circular(2));
    _paint.color = style.lineColor;
    canvas.drawRRect(bgRect, _paint);

    // 绘制文字
    textPainter.paint(canvas, Offset(bgLeft + horizontalPadding, (size.height - textHeight) / 2));
  }

  @override
  bool shouldRepaint(_TooltipPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics(_TooltipPainter oldDelegate) => false;
}

class _ProgressPainter extends CustomPainter {
  _ProgressPainter({required this.style, required this.progress, required this.gradientVisible});

  final GTProgressV3Style style;

  final double progress;

  final Paint _paint = Paint()..style = PaintingStyle.fill;

  final bool gradientVisible;
  final Radius cornerRadius = const Radius.circular(8);

  @override
  void paint(Canvas canvas, Size size) {
    {
      /// 绘制背景
      _paint.color = GTColorsV3.divider5.color;
      Rect bgRect = Rect.fromLTWH(0, 0, size.width, size.height);
      RRect roundedRect = RRect.fromRectAndRadius(bgRect, cornerRadius);
      canvas.drawRRect(roundedRect, _paint);
    }
    {
      // 绘制进度
      _paint.color = style.lineColor;
      if (gradientVisible) {
        // 纯色和渐变色比例
        const pureRatio = 71 / 87;
        // 绘制纯色
        Rect rect = Rect.fromLTWH(0, 0, size.width * progress * pureRatio, size.height);
        RRect roundedRect = RRect.fromRectAndRadius(rect, cornerRadius);
        canvas.drawRRect(roundedRect, _paint);

        // 渐变色绘制
        Rect gRect =
            Rect.fromLTWH(size.width * progress * pureRatio, 0, size.width * progress * (1 - pureRatio), size.height);
        final gPaint = Paint()
          ..shader = LinearGradient(colors: [style.lineColor, const Color(0xff00ffb2)]).createShader(gRect);
        RRect roundedGRect = RRect.fromRectAndRadius(rect, cornerRadius);
        canvas.drawRRect(roundedGRect, gPaint);
      } else {
        Rect rect = Rect.fromLTWH(0, 0, size.width * progress, size.height);
        RRect roundedRect = RRect.fromRectAndRadius(rect, cornerRadius);
        canvas.drawRRect(roundedRect, _paint);
      }
    }
  }

  @override
  bool shouldRepaint(_ProgressPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics(_ProgressPainter oldDelegate) => false;
}
